#ifdef DISPLAY_ENABLE
//logMessage(LOGLEVEL_DEBUG, "DISPLAY", "", "");
#include <LiquidCrystal.h>


// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(DISPLAY_rs, 2, DISPLAY_enable, DISPLAY_d4, DISPLAY_d5, DISPLAY_d6, DISPLAY_d7);

const int DISPLAYCursorRowMax = 4;
const int DISPLAYCursorColMax = 16;
int DISPLAYCursorCol = 0;
int DISPLAYCursorRow = 0;
unsigned long DISPLAYpreviousMillis;
int DISPLAYMode;
char DISPLAYBuffer[DISPLAYCursorRowMax][DISPLAYCursorColMax];

/*************************************** 
 * 
 * global functions
 *
 ***************************************/

void setupDisplay(){
  logMessage(LOGLEVEL_INFO, "DISPLAY", "setup Display", "");
  // set up the LCD's number of columns and rows: 
  lcd.begin(DISPLAYCursorColMax, DISPLAYCursorRowMax);
  lcd.display();
  lcdClear();
  lcdPrintln("Starting up");
  setDisplayMode(DISPLAY_MODE_OVERVIEW);
}

void printDisplayDelay() {
  unsigned long tempCurrentMillis = millis();
  unsigned long tempDiff = tempCurrentMillis - DISPLAYpreviousMillis;
  if(tempDiff > DISPLAY_DELAY || DISPLAYpreviousMillis == 0) {    
    DISPLAYpreviousMillis = tempCurrentMillis;  
    printDisplay(); 
  }
}

void printDisplay() {
    if (getDisplayMode() == DISPLAY_MODE_OVERVIEW) {
      printDisplayTemperatureAndHumidityOverview();
    }      
    if (getDisplayMode() == DISPLAY_MODE_ALL_SYSTEMS) {
      printDisplayTemperatureAndHumidityAllSystems();
    }
    if (getDisplayMode() == DISPLAY_MODE_OVERVIEW_SYSTEM_1) {
      printDisplayTemperatureAndHumidityOverviewOfSystem1();
    }
    if (getDisplayMode() == DISPLAY_MODE_OVERVIEW_SYSTEM_2) {
      printDisplayTemperatureAndHumidityOverviewOfSystem2();
    }
    if (getDisplayMode() == DISPLAY_MODE_SYSTEM_1) {
      printDisplayTemperatureAndHumidityOfSystem1();
    }
    if (getDisplayMode() == DISPLAY_MODE_SYSTEM_2) {
      printDisplayTemperatureAndHumidityOfSystem2();
    }      
}

String getHelpDISPLAYMODE(String aSeparator) {
  String tempHelp = aSeparator;
  tempHelp += "DISPLAYMODE [int: displaymode]" + aSeparator;
  tempHelp += "sets mode of display:" + aSeparator;
  tempHelp += "DISPLAY_MODE_ALL_SYSTEMS = 1" + aSeparator;
  tempHelp += "DISPLAY_MODE_OVERVIEW_SYSTEM_1 = 2" + aSeparator;
  tempHelp += "DISPLAY_MODE_OVERVIEW_SYSTEM_2 = 3" + aSeparator;
  tempHelp += "DISPLAY_MODE_SYSTEM_1 = 4" + aSeparator;
  tempHelp += "DISPLAY_MODE_SYSTEM_2 = 5" + aSeparator;
  tempHelp += "DISPLAY_MODE_OVERVIEW = 6" + aSeparator;  
  tempHelp += aSeparator;
  return tempHelp;
}
/*************************************** 
 * 
 * display implementations
 *
 ***************************************/
void printDisplayTemperatureAndHumidityOverviewOfSystem1() {
    lcdClear();
    if (SHT15SENSORS > 0) {
      printDisplayTemperatureAndHumidityShort(0);
      printDisplayTemperatureAndHumidityMinMaxShort(0);      
    }
    if (SHT15SENSORS > 1) {    
      printDisplayTemperatureAndHumidityShort(1);    
      printDisplayTemperatureAndHumidityMinMaxShort(1);      
    }
}

void printDisplayTemperatureAndHumidityOverviewOfSystem2() {
    lcdClear();
    if (SHT15SENSORS > 2) {
      printDisplayTemperatureAndHumidityShort(2);
      printDisplayTemperatureAndHumidityMinMaxShort(2);      
    }
    if (SHT15SENSORS > 3) {    
      printDisplayTemperatureAndHumidityShort(3);    
      printDisplayTemperatureAndHumidityMinMaxShort(3);
    }
}

void printDisplayTemperatureAndHumidityOfSystem1() {
    lcdClear();
    if (SHT15SENSORS > 0) {
      printDisplayTemperatureAndHumidityLong(0);
    }
    if (SHT15SENSORS > 1) {    
      printDisplayTemperatureAndHumidityLong(1);    
    }
}

void printDisplayTemperatureAndHumidityOfSystem2() {
    lcdClear();
    if (SHT15SENSORS > 2) {
      printDisplayTemperatureAndHumidityLong(2);
    }
    if (SHT15SENSORS > 3) {    
      printDisplayTemperatureAndHumidityLong(3);    
    }  
}

void printDisplayTemperatureAndHumidityOverview() {
    lcdClear();    
    printDisplayTime();
    printDisplayTemperatureLM35(0);    
    printDisplayTemperatureAndHumidityShort(0);
    if (SHT15SENSORS > 1) {
      printDisplayTemperatureAndHumidityShort(1);  
    }
}

void printDisplayTemperatureAndHumidityAllSystems() {
    lcdClear();    
    for (int i=0; i<SHT15SENSORS; i++) {
      printDisplayTemperatureAndHumidityShort(i);
    }
}

void printDisplayTemperatureLM35(int i) {
    #ifdef LM35_ENABLE
      lcdPrint("T: ", (int)getLM35Temperature(i));
      lcdPrintln("C");    
    #endif
}

void printDisplayTemperatureAndHumidityShort(int i) {
    #ifdef SHT15_ENABLE
      lcdPrint("T: ", (int)getSHT15Temperature(i));
      lcdPrint("C; H: ", (int)getSHT15Humidity(i));    
      lcdPrintln("%"); 
    #endif   
}

void printDisplayTemperatureAndHumidityLong(int i) {
    #ifdef SHT15_ENABLE
      lcdPrint("Temp: ", (int)getSHT15Temperature(i));
      lcdPrintln("C");    
      lcdPrint("Humidity: ", (int)getSHT15Humidity(i));    
      lcdPrintln("%"); 
    #endif
}

void printDisplayTemperatureAndHumidityMinMaxShort(int i) {
    #ifdef SHT15_ENABLE
      lcdPrint("T:", (int)getSHT15TemperatureMin(i));
      lcdPrint("/", (int)getSHT15TemperatureMax(i));
      lcdPrint("; H:", (int)getSHT15HumidityMin(i));
      lcdPrintln("/", (int)getSHT15HumidityMax(i));
    #endif
}

void printDisplayTime() {
    lcdPrint("Time: ");
    lcdPrintln(getTimeFormatted());
}

/*************************************** 
 * 
 * format functions & helpers
 *
 ***************************************/
int getDisplayMode() {
  return DISPLAYMode;
}

void setDisplayMode(int aValue) {
  DISPLAYMode = aValue;
}

void lcdPrint(String aMessage) {
    lcd.print(aMessage);
}

void lcdPrint(String aMessage, float aValue) {
    lcd.print(aMessage);
    lcd.print(aValue);    
}

void lcdPrint(String aMessage, int aValue) {
    lcd.print(aMessage);
    lcd.print(aValue);    
}

void lcdClear() {
//  if (!isBootrstrapCleaned) {
    lcd.clear();    
//  }
  DISPLAYCursorCol = 0;
  DISPLAYCursorRow = 0;
  lcd.setCursor(DISPLAYCursorCol, DISPLAYCursorRow);
}

void lcdPrintln(String aMessage) {    
    int lcdBugFaktor = 0;
    if (DISPLAYCursorRow < DISPLAYCursorRowMax) {
      DISPLAYCursorRow++;
    }
    lcd.print(aMessage);
    
//    for (DISPLAYCursorCol=aMessage.length(); DISPLAYCursorCol <= 16; DISPLAYCursorCol++) {
//      lcd.setCursor(DISPLAYCursorCol, DISPLAYCursorRow);
//      lcd.print(" ");
//      DISPLAYCursorCol=0;
//    }
    
    lcd.setCursor(DISPLAYCursorCol, DISPLAYCursorRow);
    
    // lcd bug?
    if(DISPLAYCursorRow > 1) {
      lcdBugFaktor = 2;
      DISPLAYCursorCol = 16;
    }    
    
    lcd.setCursor(DISPLAYCursorCol, DISPLAYCursorRow - lcdBugFaktor);
}

void lcdPrintln(String aMessage, float aValue) {    
    if (DISPLAYCursorRow < DISPLAYCursorRowMax) {
      DISPLAYCursorRow++;
    }
    lcd.print(aMessage);
    lcd.print(aValue);   
    lcd.setCursor(DISPLAYCursorCol, DISPLAYCursorRow);
}

void lcdPrintln(String aMessage, int aValue) {    
    if (DISPLAYCursorRow < DISPLAYCursorRowMax) {
      DISPLAYCursorRow++;
    }
    lcd.print(aMessage);
    lcd.print(aValue);  
    lcd.setCursor(DISPLAYCursorCol, DISPLAYCursorRow);
}

#endif
